home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 235 / Issue 235 - September 2007 - DPCS0907DVD.ISO / Extras / NetObjects Fusion / NOF10.exe / data1.cab / FSI / lib / nof / ui / TabbedMenu.js < prev    next >
Encoding:
Text File  |  2007-04-11  |  20.4 KB  |  617 lines

  1. /****i* SOURCE_FILE/INFO
  2. *
  3. * NAME
  4. *  TabbedMenu.js
  5. *
  6. * USAGE
  7. *  Part of Netobjects JavaScript Library.
  8. *
  9. * COPYRIGHT
  10. *  Copyright ⌐ 2002-2004 Website Pros, Inc.
  11. *  All Rights Reserved.
  12. *
  13. *  This is an unpublished work protected by Website Pros, Inc.
  14. *  as a trade secret, and is not to be used or disclosed except as
  15. *  expressly provided in a written license agreement executed by
  16. *  you and Website Pros, Inc.
  17. *
  18. *      <copyright@websitepros.com>
  19. *
  20. * NOTES
  21. *  JavaScript code.
  22. *****/
  23. if (!IS_isModuleInitialized("IS.NOF.UI.TabbedMenu"))
  24. {
  25. /****h* NOF_JavaScript_Library/NOF.UI.TabMenuItem
  26.     *
  27.     * NAME
  28.     *  NOF.UI.TabMenuItem
  29.     *
  30.     * DESCRIPTION
  31.     *
  32.     * External dependencies: IS.MenuItem, NOF.MenuEvent    
  33.     ****/
  34.  
  35. /**
  36. * TabbedMenu.TabMenuItem class constructor
  37. *
  38. * @param id, internal id
  39. * @param label, display label
  40. */
  41. function NOF_TabMenuItem(id, label) {
  42.     this.__proto__   = NOF_TabMenuItem.prototype;
  43.     this.SUPER( id, label );
  44.     
  45.     this.listeners      = new Array();
  46.     this.getId          = function getId(){ return this.id; };
  47.     
  48.     /**
  49.     Invoked when a menu item is clicked. It assumes the owner implements a
  50.     processEvent( Event ) method and calls it.
  51.     */
  52.     this.onClick        =   function onClick() {
  53.         this.owner.processEvent( new NOF.MenuEvent(NOF.MenuEvent.ITEM_SELECTED, this) );
  54.     }
  55. }
  56. NOF_TabMenuItem.inherits ( IS.MenuItem  ) 
  57. {
  58.     var method = NOF_TabMenuItem.prototype;
  59.     
  60.     method.release = function (){
  61.         if (this.listeners != null )
  62.             for (var i = 0; i++; i < this.listeners.length )
  63.                 this.listeners[i] == null;
  64.         
  65.         this.owner = null;
  66.         this.listeners = null;
  67.     };
  68.     
  69.     /**
  70.     Generates a qualified id for the item.
  71.     
  72.     @return the qualified id of the item as ownerId_itemId
  73.     */
  74.     method.getQualifiedId =   function () {
  75.         return this.owner.id + "_" + this.id;
  76.     };
  77.     
  78.     /**
  79.     Adds the <code>listener</code> to the listeners list
  80.     
  81.     @param listener
  82.     */
  83.     method.addListener    = function ( listener ) {
  84.         this.listeners[this.listeners.length] = listener;
  85.     }
  86.     
  87.     /**
  88.     Removes the <code>listener</code> from the listeners list
  89.     
  90.     @param listener
  91.     */
  92.     method.removeListener = function ( listener ) {
  93.         for (var i = 0; i++; i < this.listeners.length ){
  94.             try{
  95.                 if ( this.listeners[i] == listener ){
  96.                     this.listeners[i] = this.listeners[this.listeners.length];
  97.                     this.listeners.length--;
  98.                 }
  99.             }catch(e){
  100.                 //wsp_tabm_logger.severe( "could not remove listener " + i );
  101.             }
  102.         }
  103.     }
  104.     
  105.     /**
  106.     Notifies all registered listeners of the event occured
  107.     
  108.     @param event, a MenuEvent object
  109.     */
  110.     method.notifyListeners = function ( event ) {
  111.         for (var i = 0; i < this.listeners.length; i++ ){
  112.             try{
  113.                 //NOF.util_logging_ConsoleLogger_global.info ( "notifying: " + event.getID());
  114.                 if (event.getID() == NOF.MenuEvent.ITEM_SELECTED )
  115.                     this.listeners[i].menuSelected( event );
  116.                 else if (event.getID() == NOF.MenuEvent.ITEM_DESELECTED )
  117.                     this.listeners[i].menuDeselected( event );
  118.                 //NOF.util_logging_ConsoleLogger_global.info ( "notification ended: " + event.getID());
  119.             }catch(e){
  120.                 //wsp_tabm_logger.severe( "could not notify listener " + i );
  121.             }
  122.         }
  123.     }
  124. }
  125.  
  126. //NOF.__proto__.TabMenuItem = NOF_TabMenuItem; // add TabMenuItem class to NOF namespace
  127. NOF.UI.__proto__.TabMenuItem = NOF_TabMenuItem; // add TabMenuItem class to UI namespace
  128.     
  129.     /****h* NOF_JavaScript_Library/NOF.UI.TabbedMenu
  130.     *
  131.     * NAME
  132.     *  NOF.UI.TabbedMenu
  133.     *
  134.     * DESCRIPTION
  135.     *
  136.     * External dependencies: IS.Menu
  137.     *    
  138.     * USAGE:
  139.     <code>
  140.     //create a menu instance
  141.     var tabbedMenu = new NOF.UI.TabbedMenu("menuId", "NOF.variableName", owner);
  142.     
  143.     //sets the browser document to generate the menu on (via writeln method)
  144.     tabbedMenu.document = document;
  145.     
  146.     //add menu items (tabs)
  147.     var tmpItem2 =   new NOF.UI.TabMenuItem ("TabId2", "TabLabel2");
  148.     
  149.     tabbedMenu.addItem (new NOF.UI.TabMenuItem ("TabId1", "TabLabel1") );
  150.     tabbedMenu.addItem (tmpItem2 );
  151.     
  152.     tabbedMenu.selectItem( tmpItem ); //highlights the given item in the menu
  153.     </code>
  154.  
  155.     NOTES:
  156.     1. the content is decoupled now from the menu and you have to use a listner and
  157.     explicitely act on select/deselect events. TabbedMenuWindow provides the functionality
  158.     2. you should use getId() now instead of .id
  159.  
  160. //TODO:
  161.     - Add support for hooking generator functions for various parts of the menu (footer, header, etc.)
  162. ****/
  163.     
  164. /*
  165. TabbedMenu class constructor
  166.  
  167. @param id, internal id
  168. @param varName, variable name to be injected in the NOF namespace
  169. @param owner, the menu owner
  170. @param width, the width of the menu per HTML table.width
  171. @param height, the height of the menu per HTML table.height
  172. @param cellSpacing, per HTML table.cellSpacing. default is 0
  173. @param cellPadding, per HTML table.cellPadding. default is 0
  174. @param border, per HTML table.border. default is 0
  175. */
  176. function NOF_TabbedMenu( id, varName, owner, width, height, cellSpacing, cellPadding, border) {
  177.     this.__proto__   = NOF_TabbedMenu.prototype;
  178.     this.SUPER( id, varName, null , owner );
  179.     
  180.     //private interface
  181.     this.currentItem     = null;
  182.     this.previousItem    = null;
  183.     this.document        = null;
  184.     this.width           = (width != null ? width : 0);
  185.     this.height          = (height != null ? height : 0);
  186.     this.cellSpacing     = (cellSpacing != null ? cellSpacing : 0);
  187.     this.cellPadding     = (cellPadding != null ? cellPadding : 0);
  188.     this.border          = (border != null ? border : 0);
  189.     
  190.     this.tabSize         = 112;
  191.     
  192.     this.IMAGES_PATH = "../resources/images/";    
  193. }
  194.  
  195. NOF_TabbedMenu.inherits( IS.Menu ) 
  196. {
  197.     var method = NOF_TabbedMenu.prototype;
  198.     
  199.     method.setImagesPath = function (path) {
  200.         this.IMAGES_PATH = path;
  201.     }
  202.     
  203.     method.release = function (){
  204.         if (this.items != null)
  205.         {
  206.             for ( var i=0; i< this.items.length; i++ ){
  207.                 try{
  208.                     this.items[i].release();
  209.                 }catch(e){
  210.                 }
  211.                 this.items[i] = null;
  212.             }
  213.         }
  214.         
  215.         if (this.listeners != null)
  216.             for (var i = 0; i++; i < this.listeners.length )
  217.                 this.listeners[i] == null;
  218.         
  219.         this.listeners  = null;
  220.         this.document   = null;
  221.         this.items = null;
  222.         this.owner = null;
  223.     };
  224.     
  225.     method.setDocument     = function ( document ) {
  226.         if (typeof(document.getRawDoc) == 'function')
  227.             this.document      = document.getRawDoc();
  228.         else
  229.             this.document = document;
  230.     };
  231.     
  232.     /**
  233.     * getAfterTabsWidth
  234.     *
  235.     * @return the number of columns for the content are as 3 times the number of tabs + 2<br>
  236.     * each tab is comprised of three columns left, middle and right<br>
  237.     * next right to the tabs there are 2 additional spacing columns
  238.     */
  239.     method.getAfterTabsWidth =  function (){
  240.         return this.width - (this.tabSize + 4) * this.getItemCount() - 10;
  241.     };
  242.     
  243.     /**
  244.     @return the number of columns for the content are as 3 times the number of tabs + 2<br>
  245.     each tab is comprised of three columns left, middle and right<br>
  246.     next right to the tabs there are 2 additional spacing columns
  247.     */
  248.     method.getContentAreaColsNo =  function (){
  249.         return 3 * this.getItemCount() + 2;
  250.     };
  251.     
  252.     /**
  253.     Changes the source URL for the image
  254.     
  255.     @param imgId, the image name per HTML img.name
  256.     @param  src, the source URL
  257.     */
  258.     method.rollImage       = function (imgId, src){
  259.         //wsp_tabm_logger.info(imgId + "  " + src);
  260.         eval("this.document.images[ '"+ imgId +"' ].src = src;");
  261.     };
  262.     
  263.     //public interface
  264.     method.getCurrentItem  = function () {return this.currentItem;};
  265.     method.setCurrentItem  = function ( item ) {this.currentItem = item;};
  266.     
  267.     /*getter/setter for the previously selected item*/
  268.     method.getPreviousItem = function () {return this.previousItem;};
  269.     method.setPreviousItem = function ( item ) {this.previousItem = item;};
  270.     
  271.     /**
  272.     Adds the <code>listener</code> to the listeners list of each menu item
  273.     
  274.     @param listener
  275.     */
  276.     method.addListener     = function ( listener ) {
  277.         for ( var i=0; i< this.items.length; i++ )
  278.             this.items[i].addListener( listener );
  279.     };
  280.     
  281.     /**
  282.     Removes the <code>listener</code> from the listeners list of each menu item
  283.     
  284.     @param listener
  285.     */
  286.     method.removeListener  =  function ( listener ) {
  287.         for ( var i=0; i< this.items.length; i++ )
  288.             this.items[i].removeListener( listener );
  289.     };
  290.     
  291.     /**
  292.     Redraws the <code>item</code> according to the <code>asSelected</code> boolean flag.
  293.     
  294.     @param item TabbedMenuItem
  295.     @param asSelectected boolean
  296.     */
  297.     method.redrawItem      = function ( item, asSelectected ) {
  298.         if ( asSelectected ){
  299.             this.redrawItemAsSelected( item );
  300.         }else{
  301.             this.redrawItemAsDeselected( item );
  302.         }
  303.     };
  304.     
  305.     /**
  306.     Redraws the <code>item</code> by changing the appearance to a highlighted view.
  307.     
  308.     @param item TabbedMenuItem
  309.     */
  310.     method.redrawItemAsSelected = function ( item ) {
  311.         var tabId = item.getQualifiedId();
  312.         var document = this.document;
  313.         
  314.         //wsp_tabm_logger.severe( ">>>>>>>>  " + tabId + "<<<<<<<<<<<" );
  315.         
  316.         document.all["tabText"+ tabId].className  = "tabStyleHl"; //bold the tab text
  317.         
  318.         //display the selected state
  319.         document.all["tab" + tabId].style.backgroundImage       = "url('" + this.IMAGES_PATH + "tab-top-hi.gif')";
  320.         document.all["tabBottom" + tabId].style.backgroundImage = "url('" + this.IMAGES_PATH + "pix.gif')";
  321.         
  322.         //fix the margins
  323.         this.rollImage("tabLeft"  + tabId, this.IMAGES_PATH + "tab-top-hi.gif");
  324.         this.rollImage("tabRight" + tabId, this.IMAGES_PATH + "tab-top-hi.gif");
  325.         
  326.         //this is the rightPart of the previous tab
  327.         //check if is the first tab
  328.         var curPos = this.getItemPos( item.getId() );
  329.         if (curPos > 0){
  330.             var leftItem = this.items[curPos - 1];
  331.             this.rollImage("tabRight" + leftItem.getQualifiedId(), this.IMAGES_PATH + "tab-left-hi.gif");
  332.         }else{
  333.             this.rollImage("tabLeftFirst" + this.id, this.IMAGES_PATH + "tab-left-hi.gif");
  334.         }
  335.         
  336.         //this is the leftPart of the next tab
  337.         //check if is the last item
  338.         if (curPos != (this.getItemCount() - 1) ){
  339.             var rightItem = this.items[curPos + 1];
  340.             this.rollImage("tabLeft" + rightItem.getQualifiedId(), "" + this.IMAGES_PATH + "tab-right-hi.gif");
  341.         }else{
  342.             this.rollImage("tabRightLast" + this.id, "" + this.IMAGES_PATH + "tab-right-hi.gif");
  343.         }
  344.     }
  345.     
  346.     
  347.     /**
  348.     Reverts all menu items in a deselected state.
  349.     */
  350.     method.redrawAllItemsAsDeselected = function () {
  351.         //set the deselect state for the left most margin
  352.         this.rollImage("tabLeftFirst"  + this.id, "" + this.IMAGES_PATH + "pix.gif");
  353.         
  354.         for (var i=0; i<this.items.length ; i++)
  355.             this.redrawItemAsDeselected( this.items[i] );
  356.         
  357.         //set the deselect state for the right most margin
  358.         this.rollImage("tabRightLast" + this.id, "" + this.IMAGES_PATH + "pix.gif");
  359.     }
  360.     
  361.     /**
  362.     Redraws the <code>item</code> by changing the appearance to a lowered view.
  363.     
  364.     @param item TabbedMenuItem
  365.     */
  366.     method.redrawItemAsDeselected = function ( item ){
  367.         var tabId = item.getQualifiedId();
  368.         var document = this.document;
  369.         
  370.         document.all["tabText" + tabId].className  = "tabStyle"; //un-bold the tab text
  371.         
  372.         //display the normal stat
  373.         document.all["tab" + tabId].style.backgroundImage       = "url('" + this.IMAGES_PATH + "tab-top-low.gif')";
  374.         document.all["tabBottom" + tabId].style.backgroundImage = "url('" + this.IMAGES_PATH + "tab-bottom.gif')";
  375.         
  376.         //fix the margins
  377.         this.rollImage("tabLeft"  + tabId, "" + this.IMAGES_PATH + "tab-left-low.gif");
  378.         this.rollImage("tabRight" + tabId, "" + this.IMAGES_PATH + "tab-right-low.gif");
  379.     };
  380.     
  381.     
  382.     /**
  383.     Shows the <code>item</code>.
  384.     
  385.     @param item TabbedMenuItem
  386.     */
  387.     method.showItem = function ( item ){
  388.         var tabId = item.getQualifiedId();
  389.         var document = this.document;
  390.         
  391.         document.all["tabText" + tabId].style.visibility  = "visible"; //hide the tab text
  392.         
  393.         //display the normal stat
  394.         document.all["tab" + tabId].style.visibility = "visible";
  395.         
  396.         //fix the margins
  397.         //document.all["tabLeft"  + tabId].style.visibility = "visible";
  398.         document.all["tabRight" + tabId].style.visibility = "visible";
  399.     };
  400.     
  401.     /**
  402.     Hides the <code>item</code>.
  403.     
  404.     @param item TabbedMenuItem
  405.     */
  406.     method.hideItem = function ( item ){
  407.         var tabId = item.getQualifiedId();
  408.         var document = this.document;
  409.         
  410.         document.all["tabText" + tabId].style.visibility  = "hidden"; //hide the tab text
  411.         
  412.         //display the normal stat
  413.         document.all["tab" + tabId].style.visibility = "hidden";
  414.         
  415.         //fix the margins
  416.         //document.all["tabLeft"  + tabId].style.visibility = "hidden";
  417.         document.all["tabRight" + tabId].style.visibility = "hidden";
  418.     };
  419.     
  420.     /**
  421.     Event handler for all MenuEvents. Currently events different than ITEM_SELECTED
  422.     are sliently discarded.
  423.     
  424.     @param event NOF.MenuEvent
  425.     */
  426.     method.processEvent = function ( event ) {
  427.         if (event.getID() == NOF.MenuEvent.ITEM_SELECTED ){
  428.             this.getCurrentItem().notifyListeners( new NOF.MenuEvent(NOF.MenuEvent.ITEM_DESELECTED, this.getCurrentItem()) );
  429.             this.onItemSelected( event.getSource() );
  430.             this.getCurrentItem().notifyListeners( new NOF.MenuEvent(NOF.MenuEvent.ITEM_SELECTED, this.getCurrentItem()) );
  431.         }
  432.     };
  433.     
  434.     /**
  435.     Event handler for ITEM_SELECTED events. Updates the appearance of the <code>item</code> and
  436.     internal members previous/current item.
  437.     
  438.     @param TabbedMenuItem
  439.     */
  440.     method.onItemSelected = function ( item ) {
  441.         if ( this.currentItem == null)
  442.             this.currentItem = this.items[0] ;
  443.         
  444.         this.previousItem  = this.currentItem;
  445.         this.currentItem   = item; //assume the source just menuItems for now
  446.         
  447.         this.redrawAllItemsAsDeselected();
  448.         this.redrawItem( item, true );
  449.     };
  450.     
  451.     /**
  452.     See onItemSelected.
  453.     */
  454.     method.selectItem = method.onItemSelected;
  455.     
  456.     /**
  457.     Builds the menu's header as a table opening w/ three rows.<br>
  458.     First row contains the actual tabs for the navigation.<br>
  459.     The second row contains the tabs underline<br>
  460.     The third row is an opening for the content cell<br>
  461.     
  462.     @return The html representation of the menu's header
  463.     */
  464.     method.getHeader = function () {
  465.         var menuHeader = "";
  466.         
  467.         menuHeader += toHTML_H ( this );
  468.         
  469.         //first row generating clickable tabs
  470.         menuHeader +=  Item_toHTML_H ( this );
  471.         var items = this.items;
  472.         for (var i = 0; i < items.length; i++){
  473.             var menuItem = items[i];
  474.             if (menuItem.owner == null)
  475.             { menuItem.owner = this; }
  476.             
  477.             menuHeader +=  Item_toHTML_C( menuItem );
  478.         }
  479.         
  480.         menuHeader +=  Item_toHTML_F ( this );
  481.         
  482.         //second row generating tabs bottom
  483.         menuHeader +=  ItemBottom_toHTML_H ( this );
  484.         var items = this.items;
  485.         for (var i = 0; i < items.length; i++){
  486.             var menuItem = items[i];
  487.             if (menuItem.owner == null)
  488.             { menuItem.owner = this; }
  489.             
  490.             menuHeader +=  ItemBottom_toHTML_C( menuItem );
  491.         }
  492.         
  493.         var btm = ItemBottom_toHTML_F ( this );
  494.         menuHeader +=  btm;
  495.         return menuHeader;
  496.     }
  497.     
  498.     /*
  499.     In the future the entire menu could be generated as opposed to a static html for the content.<br>
  500.     Not really useful at this moment as it lacks the ability to hook a content generator.<br>
  501.     getHeader and getFooter generate the dialog's frame.
  502.     
  503.     @return The html representation of the menu's header
  504.     */
  505.     method.toHTML = function (){
  506.         var document = this.document;
  507.         
  508.         document.write ( this.getHeader() );
  509.         document.write ( this.getContent() );
  510.         document.write ( this.getFooter() );
  511.     };
  512.     
  513.     
  514.     /**
  515.     In the future the menu's content could be generated instead of a static html.<br>
  516.     getHeader and getFooter generate the dialog's frame.
  517.     
  518.     @return the initial content.
  519.     */
  520.     method.getContent = function (){ return toHTML_C( this ); }
  521.     
  522.     /*
  523.     Builds the menu's footer by closing the content cell/row and menu's table<br>
  524.     
  525.     @return The html representation of the menu's header
  526.     */
  527.     method.getFooter = function (){ return toHTML_F ( this );}
  528.     
  529.     //
  530.     // Menu and MenuItem Definition
  531.     //
  532.     function toHTML_H (menu) {
  533.         return  "<!--PropertyPage-->\n" +
  534.             "<table cellpadding=\"" + menu.cellPadding  + "\" cellspacing=\""+ menu.cellSpacing +
  535.             "\" border=\""+ menu.border +"\" width=\""+ menu.width + "\" height=\"" + menu.height + "\">\n";
  536.     }
  537.     
  538.     function toHTML_C ( menu ) {
  539.         return "Dialog Content";
  540.     }
  541.     
  542.     function Item_toHTML_H ( menu ) {
  543.         return "<tr height=20>\n"+
  544.             "\t<td width=2 border=0><img width=\"2\" height=20 alt=\"\" src=\"" + menu.IMAGES_PATH + "tab-left-hi.gif\" name=tabLeftFirst" + menu.id + "></td>"+
  545.             "\t<td rowspan=\"2\"><table cellspacing=0 cellpadding=0><tr>";
  546.     }
  547.     
  548.     function Item_toHTML_C (item, target, href) {
  549.         var itemView =
  550.             "\t<td width=\"2\"><IMG width=2 border=0 height=20 alt=\"\" src=\"" + item.owner.IMAGES_PATH + "tab-left-low.gif\" " +
  551.             "name=\"tabLeft" + item.getQualifiedId() + "\" ></td>\n" +
  552.             "\t<td id=\"tab" + item.getQualifiedId() + "\" onClick=\"" + item.owner.varName + ".getItem(\'" + item.getId() + "\').onClick();\"" +
  553.             "align=\"middle\" style=\"BACKGROUND-POSITION: 50% top; BACKGROUND-IMAGE: url(" + item.owner.IMAGES_PATH + "tab-top-low.gif); CURSOR: pointer; BACKGROUND-REPEAT: repeat-x\" width=\"" + item.owner.tabSize + "\">" +
  554.             "\t  <nobr id=\"tabText" + item.getQualifiedId() + "\" class=\"tabStyle\"> " + item.label + " </nobr></td>\n" +
  555.             "\t<td width=\"2\"><IMG height=20 alt=\"\" src=\"" + item.owner.IMAGES_PATH + "tab-right-low.gif\" width=2 border=0 " +
  556.             "name=\"tabRight" + item.getQualifiedId() + "\" ></td>\n";
  557.         
  558.         return itemView;
  559.     }
  560.     
  561.     function Item_toHTML_F ( menu ) {
  562.         return "<td width=6><img width=2 border=0 height=20 alt=\"\" src=\"" + menu.IMAGES_PATH + "pix.gif\" name=tabRightLast"+ menu.id +"></td>"+
  563.             "<td width=2><img width=1 border=0 height=1 alt=\"\" src=\"" + menu.IMAGES_PATH + "pix.gif\"></td></tr>";
  564.     }
  565.     
  566.     
  567.     function ItemBottom_toHTML_H ( menu ){
  568.         return "<tr height=2>";
  569.     }
  570.     
  571.     function ItemBottom_toHTML_C ( item ){
  572.         return "\t<td width=\"" + (item.owner.tabSize + 4) + "\" background=\"" + item.owner.IMAGES_PATH + "tab-bottom.gif\" colspan=\"3\" " +
  573.             "id=\"tabBottom" + item.getQualifiedId() + "\"><img width=\""+ (item.owner.tabSize + 4) + "\" border=0 height=2 alt=\"\" src=\"" + item.owner.IMAGES_PATH + "pix.gif\"></td>\n";
  574.         
  575.     }
  576.     
  577.     function ItemBottom_toHTML_F ( menu ){
  578.         return "    <TD background=" +menu.IMAGES_PATH + "tab-bottom.gif><IMG height=2 alt=\"\" src=\"" +menu.IMAGES_PATH + "pix.gif\" width=1 border=0></TD>" +
  579.             "    <TD width=\"100%\" background=" +menu.IMAGES_PATH + "tab-bottom.gif><IMG height=2 alt=\"\" src=\"" +menu.IMAGES_PATH + "tab-bottom.gif\" width=2 border=0></TD>" +
  580.             "  </TR>" +
  581.             "  </TABLE>" +
  582.             "  " +
  583.             "  </TD>" +
  584.             "  <TD width=\"" + menu.getAfterTabsWidth() + "\"><IMG height=1 alt=\"\" src=\"" +menu.IMAGES_PATH + "pix.gif\" width=\"" + menu.getAfterTabsWidth() + "\" border=0></TD>" +
  585.             "  <TD width=2><IMG height=1 alt=\"\" src=\"" +menu.IMAGES_PATH + "pix.gif\" width=1 border=0></TD>" +
  586.             "</TR>" +
  587.             "<TR height=2>" +
  588.             "  <TD id=tabBottomFirst width=2 background=" +menu.IMAGES_PATH + "tab-bottom.gif><IMG height=2 alt=\"\" src=\"" +menu.IMAGES_PATH + "pix.gif\" width=1 border=0></TD><!--TabsBottomLine-->" +
  589.             "  <TD background=" +menu.IMAGES_PATH + "tab-bottom.gif><IMG height=1 alt=\"\" src=\"" +menu.IMAGES_PATH + "pix.gif\" width=1 border=0></TD>" +
  590.             "  <TD width=2><IMG height=2 alt=\"\" src=\"" +menu.IMAGES_PATH + "tab-border-top-right.gif\" width=2 border=0></TD>" +
  591.             "</TR>" +
  592.             "<TR>" +
  593.             "<TD width=2 background=" +menu.IMAGES_PATH + "tab-border-left.gif><IMG height=1 alt=\"\" src=\"" +menu.IMAGES_PATH + "pix.gif\" width=1 border=0></TD><!--PropertyPageContent-->" +
  594.             "<TD style=\"PADDING-RIGHT: 5px; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; PADDING-TOP: 5px\" vAlign=top width=\"100%\" colSpan=2>";
  595.     }
  596.     
  597.     
  598.     function toHTML_F ( menu ) {
  599.         return    "\t</td>\n<!--/PropertyPageContent-->\n" +
  600.             "\t<td background=\"" +menu.IMAGES_PATH + "tab-border-right.gif\" width=\"2\"><img height=1 alt=\"\" src=\"" +menu.IMAGES_PATH + "pix.gif\" width=1 border=0></td>\n" +
  601.             "</tr>\n<!--/DialogContentRow-->\n" +
  602.             "<!--BottomBorder-->\n" +
  603.             
  604.             "<tr height=\"2\">\n"+
  605.             "\t<td width=\"2\"><img height=2 alt=\"\" src=\"" +menu.IMAGES_PATH + "tab-border-bottom-left.gif\" width=\"2\" border=\"0\"></td>\n" +
  606.             "\t<td colspan=\"2\" background=\"" +menu.IMAGES_PATH + "tab-border-bottom.gif\"><img height=1 alt=\"\" src=\"" +menu.IMAGES_PATH + "pix.gif\" width=1 border=0></td>\n" +
  607.             "\t<td width=\"2\"><img height=2 alt=\"\" src=\"" +menu.IMAGES_PATH + "tab-border-bottom-right.gif\" width=\"2\" border=\"0\"></td>\n" +
  608.             "</tr>\n" +
  609.             "<!--/BottomBorder-->\n" +
  610.             "</table>\n" +
  611.             "<!--/PropertyPage-->\n";
  612.     }
  613. }
  614.  
  615. //NOF.__proto__.TabbedMenu = NOF_TabbedMenu; //add TabMenu class to NOF namespace
  616.     NOF.UI.__proto__.TabbedMenu = NOF_TabbedMenu; //add TabMenu class to UI namespace
  617. }